# ======================================================================
# Copyright CERFACS (June 2019)
# Contributor: Adrien Suau (adrien.suau@cerfacs.fr)
#
# This software is governed by the CeCILL-B license under French law and
# abiding  by the  rules of  distribution of free software. You can use,
# modify  and/or  redistribute  the  software  under  the  terms  of the
# CeCILL-B license as circulated by CEA, CNRS and INRIA at the following
# URL "http://www.cecill.info".
#
# As a counterpart to the access to  the source code and rights to copy,
# modify and  redistribute granted  by the  license, users  are provided
# only with a limited warranty and  the software's author, the holder of
# the economic rights,  and the  successive licensors  have only limited
# liability.
#
# In this respect, the user's attention is drawn to the risks associated
# with loading,  using, modifying and/or  developing or reproducing  the
# software by the user in light of its specific status of free software,
# that  may mean  that it  is complicated  to manipulate,  and that also
# therefore  means that  it is reserved for  developers and  experienced
# professionals having in-depth  computer knowledge. Users are therefore
# encouraged  to load and  test  the software's  suitability as  regards
# their  requirements  in  conditions  enabling  the  security  of their
# systems  and/or  data to be  ensured and,  more generally,  to use and
# operate it in the same conditions as regards security.
#
# The fact that you  are presently reading this  means that you have had
# knowledge of the CeCILL-B license and that you accept its terms.
# ======================================================================

"""Rules to adapt an arbitrary circuit to the GraphOptimiser basis.

To add a rule, just add an entry in the `_rule` variable.
"""
import logging

logger = logging.getLogger("qaths.pbo_rules.graphopt")

try:
    import numpy

    from qat.pbo import VAR, GraphCircuit

    _x = VAR()

    _rules = (
        (
            [("RY", [0], _x)],
            [
                ("PH", [0], numpy.pi / 2),
                ("H", [0]),
                ("RZ", [0], _x),
                ("H", [0]),
                ("PH", [0], numpy.pi / 2),
            ],
        ),
        ([("X", [0])], [("H", [0]), ("RZ", [0], numpy.pi), ("H", [0])]),
    )

    def adapt_to_graphopt(circ):
        graph = GraphCircuit()
        graph.load_circuit(circ)
        for pattern in _rules:
            while graph.replace_pattern(*pattern):
                continue
        return graph.to_circ()


except ImportError:
    logger.warning(
        "Pattern-based optimizer (PBO) not found. You are probably using "
        "MyQLM that does not include this feature. Disabling the "
        "adapt_to_graphopt function."
    )
